﻿using RemoteDesktopLib;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Threading;

namespace RemoteDesktopClient
{
    public class Viewer : IViewer
    {
        public static Image Screen;

        //Xử lý sự kiện thay đổi màn hình
        public delegate void ImageChangeHandler(Image display);
        public static event ImageChangeHandler OnImageChange;

        //Các biến thread của service
        private ServiceHost _viewerService;
        private Thread _svcThread;
        private bool _endThread;

        /*
         * Function: ServiceThread
         * Description: Hàm chạy của thread Viewer
         */
        private void ServiceThread()
        {
            Uri baseAddress = new Uri("http://localhost:6971/Rlc/Viewer");

            try
            {
                _viewerService = new ServiceHost(typeof(Viewer), baseAddress);
                _viewerService.Open();
                while (!_endThread)
                {
                    Thread.Sleep(5000);
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex, "RD_Client");
            }
            finally
            {
                if (_viewerService.State != CommunicationState.Closed)
                {
                    _viewerService.Close();
                }
            }
        }

        /*
         * Function: StartService
         * Description: Hàm bắt đầu chạy service
         */
        public void StartService()
        {
            _svcThread = new Thread(ServiceThread);
            _svcThread.Start();
        }

        /*
         * Function: StopService
         * Description: Hàm tắt service
         */
        public void StopService()
        {
            _endThread = true;
            _svcThread.Join();
        }

        /*
         * Function: PushScreenUpdate
         * Description: Hàm tắt service
         * Params:
         *  data: mảng byte chứa dữ liệu
         */
        public void PushScreenUpdate(byte[] data)
        {
            if (data != null)
            {
                //Unpack data
                Image partial;
                Rectangle bounds;
                Guid id;
                RemoteDesktopLib.Utils.UnpackScreenCaptureData(data, out partial, out bounds, out id);

                //Cập nhật lại màn hình hiện tại
                RemoteDesktopLib.Utils.UpdateScreen(ref Screen, partial, bounds);

                UpdateScreenImage();
            }
        }

        private void UpdateScreenImage()
        {
            if (Screen != null)
            {
                if (OnImageChange != null)
                {
                    OnImageChange(Screen);
                }
            }
        }

        public string Ping()
        {
            return "Connected: ServerTime = " + DateTime.Now;
        }


        public void UploadFile(string fPath, byte[] data)
        {
            string filePath = fPath;
            FileStream fs = new FileStream(filePath, FileMode.Create,
                                           FileAccess.Write);
            fs.Write(data, 0, data.Length);
            fs.Close();
        }

        public byte[] DownloadFile(string fPath)
        {
            string filePath = fPath;
            // read the file and return the byte[]
            using (FileStream fs = new FileStream(filePath, FileMode.Open,
                                       FileAccess.Read, FileShare.Read))
            {
                byte[] buffer = new byte[fs.Length];
                fs.Read(buffer, 0, (int)fs.Length);
                return buffer;
            }
        }
    }
}
